package mathive.client.panels;

import mathive.client.ClientSudokuData;
import mathive.client.GameParent;
import mathive.client.PanelHandler;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class ArithmeticsPanel extends GameParent{

	private static final int QUESTIONS = 10;
	private static final int ADDITION = 0;
	private static final int SUBSTITUTION = 1;
	private static final int MULTIPLICATION = 2;
	private static final int DIVISION = 3;
	private static final int EASY_UPPER = 10;
	private static final int MEDIUM_UPPER = 50;
	private static final int HARD_UPPER = 100;


	private VerticalPanel mainPanel = new VerticalPanel();
	private HorizontalPanel gamePanel = new HorizontalPanel();
	private Button nextButton = new Button("Next question");
	private Button cancelButton = new Button("Cancel");
	private Label questionLabel = new Label();
	private Label scoreLabel = new Label();
	private int difficulty = 0;
	private int question = 0;
	private HTML title;
	private Label first = new Label();
	private Label function = new Label();
	private Label second = new Label();
	private Label equals = new Label("=");
	private TextBox answer = new TextBox();
	private Label diffLabel = new Label("Choose difficulty");
	private ListBox diffBox = new ListBox();
	private Button playButton = new Button("Play!");


	public ArithmeticsPanel(){

		diffBox.addItem("Difficulty");
		diffBox.addItem("Easy");
		diffBox.addItem("Medium");
		diffBox.addItem("Hard");

		title = new HTML("<h1>Arithmetics</h1>");
		questionLabel.setText("Question: " + question + " of " + QUESTIONS);
		scoreLabel.setText("Score: " + score + " of " + question);

		// Listen for mouse events on the Done button.
		nextButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if(!answer.getText().matches("[0-9]+")){		//If there is anything else than numbers entered
					Window.alert("You must enter numbers in order to continue.");
				} else {
					if(checkAnswer()){
						setScore(1);
					} else{
						setScore(0);
					}
					nextQuestion();
				}
			}
		});

		// Listen for mouse events on the cancel button.
		cancelButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				PanelHandler.showGames();
			}
		});

		// Listen for mouse events on the cancel button.
		playButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if(diffBox.getItemText(diffBox.getSelectedIndex()).equals("Easy")){
					difficulty = EASY_UPPER;
				} else if(diffBox.getItemText(diffBox.getSelectedIndex()).equals("Medium")){
					difficulty = MEDIUM_UPPER;
				} else if(diffBox.getItemText(diffBox.getSelectedIndex()).equals("Hard")){
					difficulty = HARD_UPPER;
				}
				initialize();
			}
		});

		// Listen for keyboard events in the input box.
		answer.addKeyPressHandler(new KeyPressHandler() {
			public void onKeyPress(KeyPressEvent event) {
				if (event.getCharCode() == KeyCodes.KEY_ENTER) {
					if(!answer.getText().matches("[0-9]+")){		//If there is anything else than numbers entered
						Window.alert("You may only enter numbers or leave it blank in order to continue.");
					} else {
						if(checkAnswer()){
							System.out.println("CORRECT");
							setScore(1);
						} else{
							System.out.println("WRONG");
							setScore(0);
						}
						nextQuestion();
					}
				}
			}
		});

	}
	
	private void initialize(){
		mainPanel.clear();
		
		question = 0;
		score = 0;

		questionLabel.setText("Question: " + question + " of " + QUESTIONS);
		scoreLabel.setText("Score: " + score + " of " + question);

		gamePanel.add(first);
		gamePanel.add(function);
		gamePanel.add(second);
		gamePanel.add(equals);
		gamePanel.add(answer);

		// Property must be set before anything is added
		mainPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);

		mainPanel.add(title);
		mainPanel.add(questionLabel);
		mainPanel.add(gamePanel);
		mainPanel.add(scoreLabel);
		mainPanel.add(nextButton);
		mainPanel.add(cancelButton);

		nextQuestion();
	}
	
	private void requestSettings(){
		mainPanel.clear();

		diffBox.setItemSelected(0, true);

		mainPanel.add(title);
		mainPanel.add(diffLabel);
		mainPanel.add(diffBox);
		mainPanel.add(playButton);
		
	}
	
	public Widget getPanel(){
		requestSettings();
		return mainPanel;
	}

	public Widget getPanel(int difficulty){
		if(difficulty == ClientSudokuData.EASY){
			this.difficulty = EASY_UPPER;
		} else if(difficulty == ClientSudokuData.MEDIUM){
			this.difficulty = MEDIUM_UPPER;
		} else {
			this.difficulty = HARD_UPPER;
		}

		initialize();
		return mainPanel;
	}

	private void nextQuestion(){
		question++;
		questionLabel.setText("Question: " + question + " of " + QUESTIONS);
		int action = Random.nextInt(4);
		int firstNumber = Random.nextInt(difficulty);
		int secondNumber = Random.nextInt(difficulty);
		int substitutionNumber = Random.nextInt(firstNumber);
		int divisionNumber = Random.nextInt(firstNumber);
		if(firstNumber == 0)
			firstNumber = 1;
		if(secondNumber == 0)
			secondNumber = 1;
		if(substitutionNumber == 0)
			substitutionNumber = 1;
		if(divisionNumber == 0)
			divisionNumber = 1;
		while(firstNumber%divisionNumber != 0){
			divisionNumber = Random.nextInt(firstNumber);
			if(divisionNumber == 0)
				divisionNumber = 1;
		}

		if(action == ADDITION){
			function.setText("+");
			first.setText(Integer.toString(firstNumber));
			second.setText(Integer.toString(secondNumber));
		}
		if(action == SUBSTITUTION){
			function.setText("-");
			first.setText(Integer.toString(firstNumber));
			second.setText(Integer.toString(substitutionNumber));
		}
		if(action == MULTIPLICATION){
			function.setText("*");
			first.setText(Integer.toString(firstNumber));
			second.setText(Integer.toString(secondNumber));			
		}
		if(action == DIVISION){
			function.setText("/");
			first.setText(Integer.toString(firstNumber));
			second.setText(Integer.toString(divisionNumber));			
		}
		answer.setText("");
		answer.setFocus(true);
	}

	private boolean checkAnswer(){
		int one = Integer.parseInt(first.getText());
		String funct = function.getText();
		int two = Integer.parseInt(second.getText());
		if(funct.equals("+"))
			if(one+two == Integer.parseInt(answer.getText()))
				return true;
		if(funct.equals("-"))
			if(one-two == Integer.parseInt(answer.getText()))
				return true;
		if(funct.equals("*"))
			if(one*two == Integer.parseInt(answer.getText()))
				return true;
		if(funct.equals("/"))
			if(one/two == Integer.parseInt(answer.getText()))
				return true;

		return false;
	}

	private void setScore(int newScore){
		score = score + newScore;
		scoreLabel.setText("Score: " + score + " of " + question);
		if(question == 10){
			ResultsPanel resultsPanel = new ResultsPanel();
			resultsPanel.showResult("Arithmetics", "1", score);
			mainPanel.clear();
			mainPanel.add(resultsPanel.getPanel());
		}
	}

}
